extends Node
class_name AIOpponent

var unit_manager
var board_manager
var round_manager
var economy_manager

var ai_gold: int = 10
var ai_level: int = 1
var ai_units: Array = []
var ai_strategy: String = "balanced"
var difficulty: float = 0.5  # 0.0 = easy, 1.0 = hard

var unit_data_pool: Array[UnitData] = []
var placement_timer: Timer

func _ready():
	print("AI Opponent initializing...")
	
	# Wait for scene to be ready
	await get_tree().process_frame
	
	# Find required nodes with multiple fallback methods
	unit_manager = get_node_or_null("/root/Main/Units")
	if not unit_manager:
		unit_manager = get_node_or_null("../Units")  # Try relative path
	
	board_manager = get_node_or_null("/root/Main/Board")
	if not board_manager:
		board_manager = get_node_or_null("../Board")  # Try relative path
	if not board_manager:
		# Try to find by group
		var boards = get_tree().get_nodes_in_group("board")
		if boards.size() > 0:
			board_manager = boards[0]
	
	round_manager = get_node_or_null("/root/Main/RoundManager")
	if not round_manager:
		round_manager = get_node_or_null("../RoundManager")
	
	economy_manager = get_node_or_null("/root/Main/EconomyManager")
	if not economy_manager:
		economy_manager = get_node_or_null("../EconomyManager")
	
	print("AI: UnitManager found: ", unit_manager != null, " at ", unit_manager.get_path() if unit_manager else "null")
	print("AI: BoardManager found: ", board_manager != null, " at ", board_manager.get_path() if board_manager else "null")
	print("AI: RoundManager found: ", round_manager != null)
	print("AI: EconomyManager found: ", economy_manager != null)
	
	if not unit_manager:
		print("AI ERROR: Could not find UnitManager!")
	if not board_manager:
		print("AI ERROR: Could not find BoardManager!")
		
	create_unit_pool()
	
	# Create timer for automatic unit placement
	placement_timer = Timer.new()
	placement_timer.wait_time = 2.0  # Place units every 2 seconds
	placement_timer.timeout.connect(_on_placement_timer)
	add_child(placement_timer)
	
	# Connect to round manager if available
	if round_manager and round_manager.has_signal("preparation_started"):
		round_manager.preparation_started.connect(_on_preparation_started)
		if round_manager.has_signal("battle_started"):
			round_manager.battle_started.connect(_on_battle_started)
		print("AI connected to RoundManager")
	
	print("AI Opponent ready")

func create_unit_pool():
	# Create the same units available to player
	var tank_data = UnitData.new()
	tank_data.unit_name = "Tank"
	tank_data.tier = 1
	tank_data.cost = 2
	tank_data.max_health = 200
	tank_data.attack_damage = 15
	tank_data.attack_speed = 0.8
	tank_data.movement_speed = 4
	tank_data.attack_range = 2
	tank_data.unit_class = "Tank"
	tank_data.model_color = Color(0.8, 0.3, 0.3)
	unit_data_pool.append(tank_data)
	
	var fighter_data = UnitData.new()
	fighter_data.unit_name = "Fighter"
	fighter_data.tier = 1
	fighter_data.cost = 1
	fighter_data.max_health = 100
	fighter_data.attack_damage = 20
	fighter_data.attack_speed = 1.0
	fighter_data.movement_speed = 5
	fighter_data.attack_range = 2.5
	fighter_data.unit_class = "Fighter"
	fighter_data.model_color = Color(0.8, 0.3, 0.3)
	unit_data_pool.append(fighter_data)
	
	var archer_data = UnitData.new()
	archer_data.unit_name = "Archer"
	archer_data.tier = 1
	archer_data.cost = 2
	archer_data.max_health = 80
	archer_data.attack_damage = 25
	archer_data.attack_speed = 1.2
	archer_data.movement_speed = 4.5
	archer_data.attack_range = 5
	archer_data.unit_class = "Ranged"
	archer_data.model_color = Color(0.8, 0.3, 0.3)
	unit_data_pool.append(archer_data)

func execute_turn():
	# AI decision making based on difficulty
	var decision_quality = randf()
	
	if decision_quality < difficulty:
		make_smart_decisions()
	else:
		make_random_decisions()
	
	place_units()

func make_smart_decisions():
	# Smart AI: tries to build synergies
	var synergy_counts = {}
	
	# Count existing units by class
	for unit in ai_units:
		if unit and is_instance_valid(unit):
			var unit_class = unit.get_unit_class()
			if unit_class in synergy_counts:
				synergy_counts[unit_class] += 1
			else:
				synergy_counts[unit_class] = 1
	
	# Buy units that complement synergies
	while ai_gold >= 1 and ai_units.size() < ai_level:
		var best_unit = find_best_synergy_unit(synergy_counts)
		if best_unit and ai_gold >= best_unit.cost:
			ai_gold -= best_unit.cost
			spawn_ai_unit(best_unit)
			
			if best_unit.unit_class in synergy_counts:
				synergy_counts[best_unit.unit_class] += 1
			else:
				synergy_counts[best_unit.unit_class] = 1
		else:
			break

func make_random_decisions():
	# Random AI: buys random units
	while ai_gold >= 1 and ai_units.size() < ai_level:
		var random_unit = unit_data_pool.pick_random()
		if random_unit and ai_gold >= random_unit.cost:
			ai_gold -= random_unit.cost
			spawn_ai_unit(random_unit)
		else:
			break

func find_best_synergy_unit(synergy_counts: Dictionary) -> UnitData:
	var best_unit = null
	var best_score = -1
	
	for unit_data in unit_data_pool:
		if unit_data.cost > ai_gold:
			continue
			
		var score = 0
		if unit_data.unit_class in synergy_counts:
			score = synergy_counts[unit_data.unit_class] * 10
		else:
			score = 5  # New synergy potential
		
		# Adjust score by unit tier
		score += unit_data.tier * 2
		
		if score > best_score:
			best_score = score
			best_unit = unit_data
	
	return best_unit

func spawn_ai_unit(unit_data: UnitData):
	if not unit_manager or not board_manager:
		print("AI ERROR: Cannot spawn unit - missing managers")
		print("  UnitManager: ", unit_manager)
		print("  BoardManager: ", board_manager)
		return
		
	# Find empty position in enemy zone (top 4 rows: z >= 8)
	var placed = false
	
	# Smart placement based on unit type
	var start_row = 8
	var end_row = 12
	
	if unit_data.unit_class == "Tank":
		start_row = 8  # Front rows for tanks
		end_row = 10
	elif unit_data.unit_class in ["Ranged", "Mage"]:
		start_row = 10  # Back rows for ranged
		end_row = 12
	else:
		start_row = 8  # Middle rows for fighters
		end_row = 11
	
	# Try to place unit in preferred rows first
	for z in range(start_row, end_row):
		if placed:
			break
		for x in range(21):  # Full width of board
			if board_manager.has_method("is_tile_occupied"):
				if not board_manager.is_tile_occupied(x, z):
					print("AI placing unit at: ", x, ", ", z)
					
					# Create the unit - check if unit_manager has the method
					var unit = null
					if unit_manager.has_method("spawn_unit_from_data"):
						unit = unit_manager.spawn_unit_from_data(x, z, unit_data)
					elif unit_manager.has_method("spawn_unit"):
						# Fallback to basic spawn_unit
						unit = unit_manager.spawn_unit(x, z, false)  # false = enemy unit
						if unit and unit_data:
							# Apply unit data manually
							if unit.has_method("set_unit_data"):
								unit.set_unit_data(unit_data)
					
					if unit:
						# Mark as AI unit
						if unit.has_method("set_is_player_unit"):
							unit.set_is_player_unit(false)
						unit.add_to_group("enemy_units")
						
						# Change color to red tint for enemy
						var mesh = unit.get_node_or_null("MeshInstance3D")
						if mesh:
							var mat = StandardMaterial3D.new()
							mat.albedo_color = unit_data.model_color * Color(1.2, 0.6, 0.6)  # Red tint
							mat.roughness = 0.5
							mat.metallic = 0.2
							mesh.set_surface_override_material(0, mat)
						
						ai_units.append(unit)
						placed = true
						print("AI successfully placed: ", unit_data.unit_name)
						break
	
	# If couldn't place in preferred rows, try any enemy row
	if not placed:
		for z in range(8, 12):
			if placed:
				break
			for x in range(21):
				if not board_manager.is_tile_occupied(x, z):
					var unit = unit_manager.spawn_unit_from_data(x, z, unit_data)
					if unit:
						if unit.has_method("set_is_player_unit"):
							unit.set_is_player_unit(false)
						unit.add_to_group("enemy_units")
						
						var mesh = unit.get_node_or_null("MeshInstance3D")
						if mesh:
							var mat = StandardMaterial3D.new()
							mat.albedo_color = unit_data.model_color * Color(1.2, 0.6, 0.6)
							mat.roughness = 0.5
							mat.metallic = 0.2
							mesh.set_surface_override_material(0, mat)
						
						ai_units.append(unit)
						placed = true
						print("AI placed (fallback): ", unit_data.unit_name)
						break

func place_units():
	# Rearrange units in formation
	var tanks = []
	var damage_dealers = []
	
	for unit in ai_units:
		if unit and is_instance_valid(unit):
			if unit.get_unit_class() == "Tank":
				tanks.append(unit)
			else:
				damage_dealers.append(unit)
	
	# Place tanks in front (rows 8-9)
	var tank_positions = []
	for z in range(8, 10):
		for x in range(21):
			tank_positions.append(Vector2i(x, z))
	
	# Place damage dealers in back (rows 10-11)
	var damage_positions = []
	for z in range(10, 12):
		for x in range(21):
			damage_positions.append(Vector2i(x, z))

func _on_placement_timer():
	# AI automatically buys and places units during preparation phase
	if ai_gold > 0 and ai_units.size() < get_max_units():
		execute_turn()

func _on_preparation_started():
	print("AI: Preparation phase started")
	# Start automatic unit placement
	placement_timer.start()
	
	# Give AI some income
	add_income(5)
	
	# Initial placement
	execute_turn()

func _on_battle_started():
	print("AI: Battle phase started")
	# Stop placing units during battle
	placement_timer.stop()

func get_max_units() -> int:
	# AI can have units based on level (same as player)
	return ai_level + 2  # Base 3 units at level 1

func start_ai_placement():
	"""Manually start AI unit placement (for testing)"""
	print("AI: Starting unit placement")
	placement_timer.start()
	execute_turn()

func stop_ai_placement():
	"""Manually stop AI unit placement"""
	print("AI: Stopping unit placement")
	placement_timer.stop()

# Add a debug function to test AI placement
func test_ai_placement():
	print("AI: Testing placement with 3 units")
	
	# Debug: Check if managers exist
	if not unit_manager or not board_manager:
		print("AI ERROR: Managers not found, trying to find them again...")
		
		# Try to find them again
		unit_manager = get_node_or_null("/root/Main/Units")
		board_manager = get_node_or_null("/root/Main/Board")
		
		if not unit_manager or not board_manager:
			print("AI ERROR: Still can't find managers!")
			print("  Looking for Units at: /root/Main/Units")
			print("  Looking for Board at: /root/Main/Board")
			
			# List all children of Main to debug
			var main = get_node_or_null("/root/Main")
			if main:
				print("  Main node children:")
				for child in main.get_children():
					print("    - ", child.name, " (", child.get_class(), ")")
			return
	
	ai_gold = 10  # Give AI some gold
	
	# Make sure we have units in the pool
	if unit_data_pool.is_empty():
		print("AI: Unit pool is empty, creating units...")
		create_unit_pool()
	
	# Place a tank
	var tank = unit_data_pool[0]  # Tank is first in pool
	spawn_ai_unit(tank)
	
	# Place a fighter
	await get_tree().create_timer(0.5).timeout
	var fighter = unit_data_pool[1]  # Fighter is second
	spawn_ai_unit(fighter)
	
	# Place an archer
	await get_tree().create_timer(0.5).timeout
	var archer = unit_data_pool[2]  # Archer is third
	spawn_ai_unit(archer)
	
	print("AI: Test placement complete")

func add_income(base_income: int):
	ai_gold += base_income + ai_level
	print("AI: Added income, current gold: ", ai_gold)

func level_up():
	if ai_level < 9:
		ai_level += 1
		print("AI: Leveled up to ", ai_level)

func reset():
	ai_gold = 10
	ai_level = 1
	for unit in ai_units:
		if unit and is_instance_valid(unit):
			unit.queue_free()
	ai_units.clear()
	print("AI: Reset complete")

func set_difficulty(new_difficulty: float):
	difficulty = clamp(new_difficulty, 0.0, 1.0)
	print("AI: Difficulty set to ", difficulty)

func _input(event):
	# Press 'A' key to test AI unit placement
	if event is InputEventKey and event.pressed and event.keycode == KEY_A:
		print("=== Testing AI unit placement (A key pressed) ===")
		test_ai_placement()
	
	# Press 'S' key to start continuous AI placement
	if event is InputEventKey and event.pressed and event.keycode == KEY_S:
		print("=== Starting AI automatic placement (S key pressed) ===")
		start_ai_placement()
	
	# Press 'D' key to stop AI placement
	if event is InputEventKey and event.pressed and event.keycode == KEY_D:
		print("=== Stopping AI placement (D key pressed) ===")
		stop_ai_placement()
